package pers.cj.pdos.controller;


import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import pers.cj.pdos.controller.base.BaseController;

import pers.cj.pdos.controller.entity.ResponseData;
import pers.cj.pdos.controller.entity.ResponseEntity;
import pers.cj.pdos.controller.entity.ResponseList;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.excel.ExcelSaleOrder;
import pers.cj.pdos.service.ISaleOrderService;
import pers.cj.pdos.service.ISaleService;
import pers.cj.pdos.task.CleanTempExcelTask;
import pers.cj.pdos.utils.*;
import pers.cj.pdos.vo.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Controller
@RequestMapping("/sale")
public class SaleOrderController extends BaseController {
    @Autowired
    ISaleOrderService saleOrderService;
    @Autowired
    ISaleService saleService;

    @RequiresPermissions("saleOrder:query")
    @RequestMapping("/saleOrder")
    public String saleOrder(){
        return "/saleOrder/saleOrder";
    }


    @RequiresPermissions("saleOrder:insert")
    @RequestMapping("/saleOrderNew")
    public String saleOrderNew(){
        return "/saleOrder/saleOrderNew";
    }

    @RequiresPermissions("saleOrder:insert")
    @RequestMapping("/saleOrderEdit")
    public String saleOrderEdit(Model model,String id){
        model.addAttribute("id",id);
        return "/saleOrder/saleOrderEdit";
    }

    @RequiresPermissions("saleOrder:query")
    @RequestMapping("/saleOrderDetail")
    public String saleOrderDetail(Model model,String id){
        model.addAttribute("id",id);
        return "/saleOrder/saleOrderDetail";
    }

    @ResponseBody
    @RequestMapping("/saleOrder/getList")
    public ResponseList getList(int page,
                                int limit,
                                String close,
                                String search,
                                String no,
                                String goodsName,
                                String remark,
                                String custom,
                                String deliveryDate1,
                                String deliveryDate2,
                                String makeTime1,
                                String makeTime2,
                                String storeId,
                                String userId,
                                String date1,
                                String date2,
                                String makeUserId,
                                String status){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();
        List<SaleOrderVo> saleOrderVoList = saleOrderService.listVo(company.getId(),
                page,
                limit,
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genLikeData(custom),
                Utils.genDate(deliveryDate1),
                Utils.genDate(deliveryDate2),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                storeId,
                PdosUtils.getViewOrderStoreId(userVo, null),
                PdosUtils.getViewOrderUserId(userVo, userId),
                Utils.genDate(date1),
                Utils.genDate(date2),
                makeUserId,
                Utils.genInteger(status));
        long count = saleOrderService.count(company.getId(),
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genLikeData(custom),
                Utils.genDate(deliveryDate1),
                Utils.genDate(deliveryDate2),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                storeId,
                PdosUtils.getViewOrderStoreId(userVo, null),
                PdosUtils.getViewOrderUserId(userVo, userId),
                Utils.genDate(date1),
                Utils.genDate(date2),
                makeUserId,
                Utils.genInteger(status));
        return ResponseList.success(count,saleOrderVoList);
    }

    @ResponseBody
    @RequiresPermissions("saleOrder:insert")
    @RequestMapping("/saleOrder/add")
    public ResponseEntity add(@RequestBody SaleOrderVo saleOrderVo){
        if (Utils.isEmpty(saleOrderVo.getNo())){
            return ResponseEntity.fail("编号不能为空");
        }

        if (Utils.isEmpty(saleOrderVo.getSaleOrderGoodsVoList()) && Utils.isEmpty(saleOrderVo.getSaleOrderPacketVoList())){
            return ResponseEntity.fail("您未选择任何商品");
        }

        if (saleOrderVo.getDate() == null){
            return ResponseEntity.fail("业务日期不能为空");
        }

        Company company = getCompany();


        if (saleOrderService.checkNo(saleOrderVo.getNo(),company.getId())){
            return ResponseEntity.fail("编号已被使用");
        }


        SaleOrder saleOrder = DataUtil.genEntityFromVo(SaleOrder.class,saleOrderVo);
        saleOrder.setStatus(1);//未审核状态
        saleOrder.setTransferStatus(1);
        saleOrder.setMakeUserId(getLoginUserId());
        saleOrder.setMakeTime(new Date());
        DataUtil.processEntity(company,saleOrder);

        GoodsUtil goodsUtil = new GoodsUtil(null,saleOrderVo.getSaleOrderGoodsVoList(),saleOrderVo.getSaleOrderPacketVoList());
        BigDecimal totalAmount = goodsUtil.getTotalAmount();
        if (saleOrder.getDiscountFlag() == 1) {
            BigDecimal amount = (totalAmount.multiply(saleOrder.getDiscountRate()).divide(new BigDecimal(100)));
            saleOrder.setDiscountAmt(totalAmount.subtract(amount)); //折扣金额 = 总金额- 折后金额
        } else {
            BigDecimal amount = (totalAmount.subtract(saleOrder.getDiscountAmt()));
            saleOrder.setDiscountRate(new BigDecimal(100).multiply(amount).divide(totalAmount,4, RoundingMode.HALF_UP)); //折扣率 = 100*折后金额 / 总金额
        }



        List<SaleOrderGoods> saleOrderGoodsList = new ArrayList<>();
        if (!Utils.isEmpty(saleOrderVo.getSaleOrderGoodsVoList())) {
            for ( SaleOrderGoodsVo vo : saleOrderVo.getSaleOrderGoodsVoList()) {
                SaleOrderGoods entity = DataUtil.genEntityFromVo(SaleOrderGoods.class, vo);
                DataUtil.processEntity(company,entity);
                entity.setSaleOrderId(saleOrder.getId());
                entity.setHasNumber(new BigDecimal(0));
                entity.setWaitNumber(entity.getNumber());
                saleOrderGoodsList.add(entity);
            }
        }

        List<SaleOrderPacket> saleOrderPacketList = new ArrayList<>();
        List<SaleOrderPacketGoods> saleOrderPacketGoodsList = new ArrayList<>();
        if (!Utils.isEmpty(saleOrderVo.getSaleOrderPacketVoList())) {
            for ( SaleOrderPacketVo vo : saleOrderVo.getSaleOrderPacketVoList()) {
                SaleOrderPacket entity = DataUtil.genEntityFromVo(SaleOrderPacket.class, vo);
                DataUtil.processEntity(company,entity);
                entity.setSaleOrderId(saleOrder.getId());
                entity.setHasNumber(new BigDecimal(0));
                entity.setWaitNumber(entity.getNumber());
                saleOrderPacketList.add(entity);

                for (SaleOrderPacketGoodsVo pgv:vo.getPacketGoodsVoList()) {
                    SaleOrderPacketGoods pg = DataUtil.genEntityFromVo(SaleOrderPacketGoods.class, pgv);
                    DataUtil.processEntity(company,pg);
                    pg.setSaleOrderId(entity.getSaleOrderId());
                    pg.setSaleOrderPacketId(entity.getId());
                    saleOrderPacketGoodsList.add(pg);
                }
            }
        }


        saleOrderService.insert(saleOrder,saleOrderGoodsList,saleOrderPacketList,saleOrderPacketGoodsList);
        return ResponseEntity.success();
    }

    @ResponseBody
    @RequiresPermissions("saleOrder:insert")
    @RequestMapping("/saleOrder/update")
    public ResponseEntity update(@RequestBody SaleOrderVo saleOrderVo){


        if (Utils.isEmpty(saleOrderVo.getNo())){
            return ResponseEntity.fail("编号不能为空");
        }

        if (saleOrderVo.getDate() == null){
            return ResponseEntity.fail("业务日期不能为空");
        }

        if (Utils.isEmpty(saleOrderVo.getSaleOrderGoodsVoList()) && Utils.isEmpty(saleOrderVo.getSaleOrderPacketVoList())){
            return ResponseEntity.fail("您未选择任何商品");
        }


        Company company = getCompany();
        SaleOrder saleOrder = DataUtil.genEntityFromVo(SaleOrder.class,saleOrderVo);
        saleOrder.setStatus(1);//未审核状态
        saleOrder.setTransferStatus(1);
        saleOrder.setMakeUserId(getLoginUserId());
        saleOrder.setMakeTime(new Date());
        DataUtil.processEntity(false, company,saleOrder);

        GoodsUtil goodsUtil = new GoodsUtil(null,saleOrderVo.getSaleOrderGoodsVoList(),saleOrderVo.getSaleOrderPacketVoList());
        BigDecimal totalAmount = goodsUtil.getTotalAmount();
        if (saleOrder.getDiscountFlag() == 1) {
            BigDecimal amount = (totalAmount.multiply(saleOrder.getDiscountRate()).divide(new BigDecimal(100)));
            saleOrder.setDiscountAmt(totalAmount.subtract(amount)); //折扣金额 = 总金额- 折后金额
        } else {
            BigDecimal amount = (totalAmount.subtract(saleOrder.getDiscountAmt()));
            saleOrder.setDiscountRate(new BigDecimal(100).multiply(amount).divide(totalAmount,4, RoundingMode.HALF_UP)); //折扣率 = 100*折后金额 / 总金额
        }

        List<SaleOrderGoods> saleOrderGoodsList = new ArrayList<>();
        if (!Utils.isEmpty(saleOrderVo.getSaleOrderGoodsVoList())) {
            for ( SaleOrderGoodsVo vo : saleOrderVo.getSaleOrderGoodsVoList()) {
                SaleOrderGoods entity = DataUtil.genEntityFromVo(SaleOrderGoods.class, vo);
                DataUtil.processEntity(company,entity);
                entity.setSaleOrderId(saleOrder.getId());
                entity.setHasNumber(new BigDecimal(0));
                entity.setWaitNumber(entity.getNumber());
                saleOrderGoodsList.add(entity);
            }
        }

        List<SaleOrderPacket> saleOrderPacketList = new ArrayList<>();
        List<SaleOrderPacketGoods> saleOrderPacketGoodsList = new ArrayList<>();
        if (!Utils.isEmpty(saleOrderVo.getSaleOrderPacketVoList())) {
            for ( SaleOrderPacketVo vo : saleOrderVo.getSaleOrderPacketVoList()) {
                SaleOrderPacket entity = DataUtil.genEntityFromVo(SaleOrderPacket.class, vo);
                DataUtil.processEntity(company,entity);
                entity.setSaleOrderId(saleOrder.getId());
                entity.setHasNumber(new BigDecimal(0));
                entity.setWaitNumber(entity.getNumber());
                saleOrderPacketList.add(entity);

                for (SaleOrderPacketGoodsVo pgv:vo.getPacketGoodsVoList()) {
                    SaleOrderPacketGoods pg = DataUtil.genEntityFromVo(SaleOrderPacketGoods.class, pgv);
                    DataUtil.processEntity(company,pg);
                    pg.setSaleOrderId(entity.getSaleOrderId());
                    pg.setSaleOrderPacketId(entity.getId());
                    saleOrderPacketGoodsList.add(pg);
                }
            }
        }

        saleOrderService.update(saleOrder,saleOrderGoodsList, saleOrderPacketList, saleOrderPacketGoodsList);
        return ResponseEntity.success();
    }


    @ResponseBody
    @RequiresPermissions("saleOrder:close")
    @RequestMapping("/saleOrder/close")
    public ResponseEntity close(@RequestBody SaleOrder saleOrder){
        try {
            //检查是否已经关闭
            if (saleOrderService.checkClose(saleOrder)){
                return ResponseEntity.fail("该单据已被关闭，不能重复关闭");
            }


            SaleOrder temp = new SaleOrder();
            temp.setId(saleOrder.getId());
            temp.setClose(true);
            saleOrderService.updateById(temp);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("作废失败");
        }
    }

    @ResponseBody
    @RequiresPermissions("saleOrder:close")
    @RequestMapping("/saleOrder/batchClose")
    public ResponseEntity batchClose(@RequestBody List<SaleOrder> list){
        if (Utils.isEmpty(list)){
            return ResponseEntity.fail("未选择数据");
        }
        try {
            saleOrderService.batchClose(list);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("作废失败");
        }
    }

    @ResponseBody
    @RequiresPermissions("saleOrder:verify")
    @RequestMapping("/saleOrder/batchVerify")
    public ResponseEntity batchVerify(@RequestBody List<SaleOrder> list){
        if (Utils.isEmpty(list)){
            return ResponseEntity.fail("为选择数据");
        }
        try {

            saleOrderService.batchVerify(getLoginUserId(), list);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("审核失败");
        }
    }

    @ResponseBody
    @RequiresPermissions("saleOrder:verify")
    @RequestMapping("/saleOrder/batchBackVerify")
    public ResponseEntity batchBackVerify(@RequestBody List<SaleOrder> list){
        if (Utils.isEmpty(list)){
            return ResponseEntity.fail("为选择数据");
        }
        try {
            saleOrderService.batchBackVerify(list);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("反审核失败");
        }
    }

    @ResponseBody
    @RequiresPermissions("saleOrder:insert")
    @RequestMapping("/saleOrder/updateImage")
    public ResponseEntity updateImage(@RequestBody SaleOrder saleOrder){
        try {
            SaleOrder temp = new SaleOrder();
            temp.setId(saleOrder.getId());
            temp.setImage(saleOrder.getImage());
            saleOrderService.updateById(temp);
            return ResponseEntity.success();
        }catch (Exception e) {
            return ResponseEntity.fail("更新图片失败");
        }
    }

    @ResponseBody
    @RequestMapping("/saleOrder/getVoById")
    public ResponseData getVoById(String id){
        SaleOrderVo saleOrderVo = saleOrderService.getVoById(id);
        return ResponseData.success(saleOrderVo);
    }

    @ResponseBody
    @RequestMapping("/saleOrder/listVoByIds")
    public ResponseData listVoByIds(@RequestBody List<String> ids){
        if (Utils.isEmpty(ids)){
            return ResponseData.fail("id不能为空");
        }
        List<SaleOrderVo> list = saleOrderService.listVoByIds(ids);
        return ResponseData.success(list);
    }


    @ResponseBody
    @RequiresPermissions("saleOrder:export")
    @RequestMapping("/saleOrder/export")
    public ResponseData export(String close,
                               String search,
                               String no,
                               String goodsName,
                               String remark,
                               String custom,
                               String deliveryDate1,
                               String deliveryDate2,
                               String makeTime1,
                               String makeTime2,
                               String storeId,
                               String userId,
                               String date1,
                               String date2,
                               String makeUserId,
                               String status){
        Company company = getCompany();
        UserVo userVo = getLoginUserVo();
        List<SaleOrderVo> saleOrderVoList = saleOrderService.listVo(company.getId(),
                null,
                null,
                Utils.genBoolean(close),
                Utils.genLikeData(search),
                Utils.genLikeData(no),
                Utils.genLikeData(goodsName),
                Utils.genLikeData(remark),
                Utils.genLikeData(custom),
                Utils.genDate(deliveryDate1),
                Utils.genDate(deliveryDate2),
                Utils.genDate(makeTime1),
                Utils.genDate(makeTime2),
                storeId,
                PdosUtils.getViewOrderStoreId(userVo, null),
                PdosUtils.getViewOrderUserId(userVo, userId),
                Utils.genDate(date1),
                Utils.genDate(date2),
                makeUserId,
                Utils.genInteger(status));

        String fileName = "销售订单列表" + DateUtils.getDate(new Date(), DateUtils.YYYYMMDDHHMMSSSS) + ".xlsx";
        try {
            String path = FileProperUtil.getInstance().getVal("excel.temp");
            OutputStream out = new FileOutputStream(path+fileName);
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,true);
            Sheet sheet1 = new Sheet(1,0, ExcelSaleOrder.class);
            sheet1.setSheetName("销售订单信息");
            writer.write(genExcelSaleOrderList(saleOrderVoList), sheet1);
            writer.finish();
            out.close();
            CleanTempExcelTask.put(fileName,new Date().getTime());
            return ResponseData.success(fileName);
        } catch (IOException e) {
            return ResponseData.fail("销售订单列表导出失败");
        }
    }

    private List<ExcelSaleOrder> genExcelSaleOrderList(List<SaleOrderVo> saleOrderVoList) {
        BusinessSet businessSet = getBusinessSet();
        List<ExcelSaleOrder> list = new ArrayList<>();
        for (SaleOrderVo saleOrderVo : saleOrderVoList){
            ExcelSaleOrder excel = new ExcelSaleOrder();
            excel.setDate(DateUtils.getDate(saleOrderVo.getDate(), DateUtils.YYYY_MM_DD));
            excel.setDeliveryData(saleOrderVo.getDeliveryDate()==null ? "": DateUtils.getDate(saleOrderVo.getDeliveryDate(), DateUtils.YYYY_MM_DD));
            excel.setNo(saleOrderVo.getNo());

            if (saleOrderVo.getStatus() == 1) {
                excel.setStatus("未审核");
            } else if (saleOrderVo.getStatus() == 2) {
                excel.setStatus("审核未转销售");
            } else if (saleOrderVo.getStatus() == 3) {
                excel.setStatus("转销售");
            } else {
                excel.setStatus("");
            }

            if (saleOrderVo.getVerifyUser()!=null) {
                excel.setVerifyUser(saleOrderVo.getVerifyUser().getName());
            } else {
                excel.setVerifyUser("");
            }
            excel.setCustomNo(saleOrderVo.getCustom().getNo());
            excel.setCustomName(saleOrderVo.getCustom().getName());
            String goods = "";
            BigDecimal number = new BigDecimal(0);
            BigDecimal amount = new BigDecimal(0);
            if (!Utils.isEmpty(saleOrderVo.getSaleOrderGoodsVoList())) {
                for (SaleOrderGoodsVo saleOrderGoodsVo : saleOrderVo.getSaleOrderGoodsVoList()) {
                    number = number.add(saleOrderGoodsVo.getNumber());
                    amount = amount.add(saleOrderGoodsVo.getAmount());
                    goods += saleOrderGoodsVo.getGoodsVo().getName() + "、";
                }
            }

            if (!Utils.isEmpty(saleOrderVo.getSaleOrderPacketVoList())) {
                for (SaleOrderPacketVo vo : saleOrderVo.getSaleOrderPacketVoList()) {
                    number = number.add(vo.getNumber());
                    amount = amount.add(vo.getAmount());
                    goods += vo.getPacketName() + "、";
                }
            }

            if (!Utils.isEmpty(goods)) {
                goods = goods.substring(0, goods.length() - 1);
            }
            excel.setGoods(goods);
            excel.setNumber(PdosUtils.getNumber(number,businessSet));
            excel.setDiscountAmt(PdosUtils.getPrice(saleOrderVo.getDiscountAmt(),businessSet));

            excel.setAmount(PdosUtils.getPrice(saleOrderVo.getTotalAmt(),businessSet));
            excel.setUser(saleOrderVo.getUser().getName());
            excel.setMakeUser(saleOrderVo.getMakeUser().getName());
            excel.setRemark(saleOrderVo.getRemark());
            excel.setClose(saleOrderVo.getClose() ? "是":"否");
            list.add(excel);
        }
        return list;
    }


    @ResponseBody
    @RequestMapping(value = "/saleOrder/uploadImg", method = RequestMethod.POST)
    public ResponseData uploadImg(MultipartFile imageFile) {
        return processUploadImg(imageFile, "saleOrder");
    }
}
